Profile picture

[k8s] 쿠버네티스에서의 서비스 디스커버리 이해와 구현 예제

JaehyoJJAng2023년 05월 15일

개요

쿠버네티스는 마이크로서비스 아키텍처를 운영할 때 필수적인 서비스 디스커버리 기능을 기본적으로 제공합니다!

여러 파드(Pod)가 동적으로 생성되고 소멸되더라도,

서비스(Service) 리소스를 통해 안정적인 네트워크 접근과 통신이 가능해집니다.


이번 포스팅에서는 쿠버네티스 내에서 서비스 디스커버리가 어떻게 동작하는지와 그 구현 예제를 살펴보도록 할게요!


서비스 디스커버리란?

서비스 디스커버리는 네트워크 상에서 서비스의 위치(주로 IP 주소와 포트)를 자동으로 찾아내는 메커니즘을 의미합니다.

특히 마이크로서비스 아키텍처에서는 여러 서비스가 동적으로 생성되고 소멸되기 때문에,

서비스 위치를 수동으로 관리하는 것은 비효율적이고 거의 불가능에 가깝습니다.

그래서 서비스 디스커버리가 꼭 필요합니다!

쿠버네티스에서는 이를 매우 간편하고 효율적으로 지원하는데요, 이제 쿠버네티스에서 서비스 디스커버리가 어떻게 동작하는지 자세히 살펴보겠습니다.


DNS 기반 디스커버리

쿠버네티스는 클러스터 내부에 DNS 서버를 운영하여 서비스 디스커버리를 지원해요.

각 서비스는 고유한 DNS 이름을 가지며, 형식은 다음과 같습니다!

<service-name>.<namespace>.svc.cluster.local

예를 들어, my-service라는 서비스가 default라는 네임스페이스에 있다면,

my-service.default.svc.cluster.local로 접근할 수 있는거죠!


그렇다면 DNS 방식의 디스커버리는 어떤 장점이 있을까요?

  • 서비스의 IP 주소를 동적으로 확인 가능
  • 서비스 이름만 알면 되므로 애플리케이션 코드가 간단해짐
  • 서비스가 변경되더라도 DNS를 통해 최신 IP를 가져옴

DNS 방식이 더 유연하고 실시간 업데이트가 가능하기 때문에, 대부분의 경우 이 방식을 사용하는 것을 권장하고 있어요!


2. 환경변수 기반 디스커버리스

Pod가 생성될 때, 쿠버네티스는 해당 네임스페이스 내의 모든 서비스에 대한 환경 변수를 자동으로 주입합니다.

이 환경 변수에는 서비스의 IP 주소와 포트 정보가 포함됩니다.

예를 들어, my-service라는 서비스가 있다고 가정하면,

Pod 내에서 아래와 같은 환경 변수를 확인할 수 있습니다:

  • MY_SERVICE_SERVICE_HOST: 서비스의 IP 주소
  • MY_SERVICE_SERVICE_PORT: 서비스의 포트 번호

단점

  • 환경 변수는 Pod 생성 시점에 주입되므로, Pod 실행 중에 서비스가 변경되면 업데이트되지 않습니다.
  • 네임스페이스 내 모든 서비스의 정보가 주입되므로 불필요한 데이터가 포함될 수 있습니다.

따라서 환경 변수 방식은 주로 레거시 애플리케이션과의 호환성을 위해 사용되며,

최신 애플리케이션에서는 DNS 방식을 권장해요!


서비스 디스커버리 예제

아래는 간단한 웹 서버(nginx)를 대상으로 한 Deployment와 이를 외부에 노출하기 위한 Service 객체의 YAML 예제입니다.


1. Deployment 생성 예제

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

설명

  • 위의 Deployment는 nginx 이미지를 기반으로 3개의 파드를 생성하며, 각 파드는 app: nginx 라벨을 가지고 있습니다.

2. Service 객체 생성 예제

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: ClusterIP

설명

  • selector 필드는 Deployment에서 생성된 app: nginx 라벨을 가진 파드를 선택합니다.
  • 클러스터 내부에서만 접근 가능한 ClusterIP 타입의 서비스로 생성되며, 클러스터 내 다른 파드들은 nginx-service라는 DNS 이름을 통해 nginx 파드에 접근할 수 있습니다.

3. 예제 활용

이제 다른 파드나 애플리케이션은 내부 네트워크에서 nginx-service라는 이름으로 nginx 웹 서버에 접근할 수 있습니다.

예를 들어, 별도의 테스트 파드에서 curl http://nginx-service 명령어를 실행하면 해당 서비스로 라우팅되어 응답을 받을 수 있습니다!


Loading script...